package com.misc.tunewsreader;

public class OwnBase64 {
	private final static char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
			.toCharArray();
	private static int[] toInt = new int[128];

	static {
		for (int i = 0; i < ALPHABET.length; i++) {
			toInt[ALPHABET[i]] = i;
		}
	}

	/**
	 * Decode a base64 encoded string
	 * 
	 * @param base_str
	 *            base64 encoded string
	 * @return Decoded string
	 */
	public static byte[] decode(String base_str) {
		int delta = base_str.endsWith("==") ? 2 : base_str.endsWith("=") ? 1
				: 0;

		byte[] buffer = new byte[base_str.length() * 3 / 4 - delta];
		int mask = 0xff;
		int index = 0;
		for (int i = 0; i < base_str.length(); i += 4) {
			int char_1 = toInt[base_str.charAt(i)];
			int char_2 = toInt[base_str.charAt(i + 1)];
			buffer[index++] = (byte) (((char_1 << 2) | (char_2 >> 4)) & mask);
			if (index >= buffer.length) {
				return buffer;
			}
			int char_3 = toInt[base_str.charAt(i + 2)];
			buffer[index++] = (byte) (((char_2 << 4) | (char_3 >> 2)) & mask);
			if (index >= buffer.length) {
				return buffer;
			}
			int char_4 = toInt[base_str.charAt(i + 3)];
			buffer[index++] = (byte) (((char_3 << 6) | char_4) & mask);
		}
		return buffer;
	}

	/**
	 * Encodes a string to base64
	 * 
	 * @param buf
	 *            the byte array (not null)
	 * @return the translated base64 string
	 */
	public static String encode(byte[] buf) {
		int size = buf.length;
		char[] ar = new char[((size + 2) / 3) * 4];
		int a = 0;
		int i = 0;
		while (i < size) {
			byte b0 = buf[i++];
			byte b1 = (i < size) ? buf[i++] : 0;
			byte b2 = (i < size) ? buf[i++] : 0;

			int mask = 0x3F;
			ar[a++] = ALPHABET[(b0 >> 2) & mask];
			ar[a++] = ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask];
			ar[a++] = ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask];
			ar[a++] = ALPHABET[b2 & mask];
		}
		switch (size % 3) {
		case 1:
			ar[--a] = '=';
		case 2:
			ar[--a] = '=';
		}
		return new String(ar);
	}

}
